package com.glsc.ngateway.platform.service.cmdb;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.glsc.ngateway.common.api.common.enums.DictConstant;
import com.glsc.ngateway.common.base.domain.mysql.cmdb.CmdbChangeLog;
import com.glsc.ngateway.common.base.domain.mysql.cmdb.CmdbCpuStandard;
import com.glsc.ngateway.common.base.domain.mysql.gateway.platform.flow.cmdb.FlowFormPartStandardModify;
import com.glsc.ngateway.common.base.exception.PlatformException;
import com.glsc.ngateway.common.base.repo.mysql.cmdb.CmdbChangeLogRepository;
import com.glsc.ngateway.common.base.repo.mysql.cmdb.CmdbCpuStandardRepository;
import com.glsc.ngateway.common.base.repo.mysql.gateway.platform.flow.cmdb.FlowFormPartStandardModifyRepo;
import com.glsc.ngateway.platform.utils.AssertOverride;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.*;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Optional;

import static com.glsc.ngateway.common.api.common.enums.DictConstant.*;

@Service
public class CmdbCpuStandardService {

    @Autowired
    private SequenceProductService sequenceProductService;
    @Autowired
    private CmdbCpuStandardRepository cmdbCpuStandardRepository;
    @Autowired
    private CmdbChangeLogRepository cmdbChangeLogRepository;
    @Autowired
    private FlowFormPartStandardModifyRepo flowFormPartStandardModifyRepo;

    public Object search(String type, Object paramsObj) {
        JSONObject objParmams = JSONObject.parseObject(JSONObject.toJSONString(paramsObj)).entrySet().stream()
                .filter(entry -> !entry.getValue().toString().isEmpty())
                .collect(JSONObject::new, (obj, entry) -> obj.put(entry.getKey(), entry.getValue()), JSONObject::putAll);

        if (StrUtil.isEmpty(objParmams.getString("orderByDirection"))) {
            objParmams.put("orderByDirection", "DESC");
        }
        if (StrUtil.isEmpty(objParmams.getString("orderByField"))) {
            objParmams.put("orderByField", "id");
        }
        Sort sort = Sort.by(Sort.Direction.fromString(objParmams.getString("orderByDirection")), objParmams.getString("orderByField"));

        Pageable pageable = PageRequest.of(objParmams.getInteger("pageNo") - 1, objParmams.getInteger("pageSize"), sort);

        if (CMDB_CPU_STANDARD.equals(type)) {
            CmdbCpuStandard paramSearchDto = JSONObject.parseObject(JSONObject.toJSONString(objParmams), CmdbCpuStandard.class);
            Page<CmdbCpuStandard> result = cmdbCpuStandardRepository.searchByParam(pageable, paramSearchDto);
            return result;
        }


        return null;
    }

    public CmdbCpuStandard findByStandardCode(String cpuStandardCode){
        AssertOverride.hasLength(cpuStandardCode,"规格号为空");
        CmdbCpuStandard standard = cmdbCpuStandardRepository.findOneByCpuStandardCode(cpuStandardCode);
        //填充关联信息
        return standard;
    }

    /**
     * @param cmdbCpuStandard
     * @param account         操作人员
     */
    public void addOrUpdate(CmdbCpuStandard cmdbCpuStandard, String account,String cmdbConfirm) {
        int addOrUpdateFlag = 0;
        cmdbCpuStandard.setIsDelete(NO_DELETE);
        CmdbChangeLog log = new CmdbChangeLog();
        if (cmdbCpuStandard.getId() != null) {
            //修改
            log.setChangeType(DictConstant.UPDATE_STRING);
            addOrUpdateFlag = 2;
        } else {
            //新增
            log.setChangeType(DictConstant.ADD_STRING);
            //自动生成编号
            String code = sequenceProductService.buildSequence(CMDB_CPU_STANDARD);
            cmdbCpuStandard.setCpuStandardCode(code);
            addOrUpdateFlag = 1;
        }
        //校验重复
        checkUnique(cmdbCpuStandard,addOrUpdateFlag,cmdbConfirm);
        log.setChangeContent(JSONObject.toJSONString(cmdbCpuStandard));
        log.setChangeFrom(CMDB_CPU_STANDARD);
        log.setChangeId(cmdbCpuStandard.getId() != null ? cmdbCpuStandard.getId().toString() : null);
        log.setChangeUser(account);
        cmdbChangeLogRepository.save(log);
        cmdbCpuStandardRepository.save(cmdbCpuStandard);
    }

    private void checkUnique(CmdbCpuStandard cmdbCpuStandard, int addOrUpdateFlag,String cmdbConfirm) {
        if (addOrUpdateFlag == 1){
            findSameName(cmdbCpuStandard,cmdbConfirm);
            findSamePartNum(cmdbCpuStandard,cmdbConfirm);
        } else {
            //修改情况，要把已有结果查询出来，如果有变化还要校验
            Optional<CmdbCpuStandard> result = cmdbCpuStandardRepository.findById(cmdbCpuStandard.getId());
            if (result.isPresent()){
                if (! result.get().getName().equals(cmdbCpuStandard.getName())){
                    if (result.get().getIsDelete().equals(NO_DELETE)){
                        findSameName(cmdbCpuStandard,cmdbConfirm);
                    }
                }
                if (! result.get().getPartNum().equals(cmdbCpuStandard.getPartNum())){
                    if (result.get().getIsDelete().equals(NO_DELETE)){
                        findSamePartNum(cmdbCpuStandard,cmdbConfirm);
                    }
                }
                //修改情况存在未删除的记录
            } else {
                findSameName(cmdbCpuStandard,cmdbConfirm);
                findSamePartNum(cmdbCpuStandard,cmdbConfirm);
            }
        }
    }

    public void findSameName(CmdbCpuStandard cmdbCpuStandard, String cmdbConfirm) {
        if (StrUtil.isNotEmpty(cmdbCpuStandard.getName())) {
            List<CmdbCpuStandard> result = cmdbCpuStandardRepository.findAllByNameAndIsDelete(cmdbCpuStandard.getName(), NO_DELETE);
            if (CollectionUtil.isNotEmpty(result)) {
                throw PlatformException.errorWithOutMail("规格名称重复");
            }
            if (!StrUtil.equals(CMDB_CONFIRM,cmdbConfirm)){
                List<FlowFormPartStandardModify> flowForms = flowFormPartStandardModifyRepo.findFlowCpuStandardName(cmdbCpuStandard.getName());
                if (CollectionUtil.isNotEmpty(flowForms)){
                    throw PlatformException.errorWithOutMail("有发起过的流程"+flowForms.get(0).getProcessTitle()+"存在相同的cpu规格名称");
                }
            }
        }
    }

    public void findSamePartNum(CmdbCpuStandard cmdbCpuStandard,String cmdbConfirm) {
        if (StrUtil.isNotEmpty(cmdbCpuStandard.getPartNum())){
            List<CmdbCpuStandard> result = cmdbCpuStandardRepository.findAllByPartNumAndIsDelete(cmdbCpuStandard.getPartNum(), NO_DELETE);
            if (CollectionUtil.isNotEmpty(result)){
                throw PlatformException.errorWithOutMail("规格配件号重复");
            }
            if (!StrUtil.equals(CMDB_CONFIRM,cmdbConfirm)){
                List<FlowFormPartStandardModify> flowForms = flowFormPartStandardModifyRepo.findFlowCpuPartNum(cmdbCpuStandard.getPartNum());
                if (CollectionUtil.isNotEmpty(flowForms)){
                    throw PlatformException.errorWithOutMail("有发起过的流程"+flowForms.get(0).getProcessTitle()+"存在相同的cpu规格配件号");
                }
            }
        }
    }

    public void delete(CmdbCpuStandard cmdbCpuStandard, String account) {
        CmdbChangeLog log = new CmdbChangeLog();
        log.setChangeContent(JSONObject.toJSONString(cmdbCpuStandard));
        log.setChangeFrom(CMDB_CPU_STANDARD);
        log.setChangeId(cmdbCpuStandard.getId().toString());
        log.setChangeUser(account);
        log.setChangeType(DELETE_STRING);
        Optional<CmdbCpuStandard> optional = cmdbCpuStandardRepository.findById(cmdbCpuStandard.getId().intValue());
        if (optional.isPresent()) {
            CmdbCpuStandard bean = optional.get();
            bean.setIsDelete(DELETED);
            cmdbCpuStandardRepository.save(bean);
            cmdbChangeLogRepository.save(log);
        } else {
            throw PlatformException.errorWithOutMail("删除记录不存在");
        }
    }

    public void deleteByCodeList(List<String> codes, String account) {
        CmdbChangeLog log = new CmdbChangeLog();
        log.setChangeContent(JSONObject.toJSONString(codes));
        log.setChangeFrom(CMDB_CPU_STANDARD);
        log.setChangeUser(account);
        log.setChangeType(DELETE_BATCH_STRING);
        cmdbChangeLogRepository.save(log);
        cmdbCpuStandardRepository.updateIsDeleteByCodes(DELETED, codes);

    }

    public CmdbCpuStandard findCmdbCpuStandardByName(String name) {
        if (StringUtils.isNotBlank(name)) {
            List<CmdbCpuStandard> list = cmdbCpuStandardRepository.findAll(Example.of(CmdbCpuStandard.builder().name(name).build()));
            if (CollectionUtil.isNotEmpty(list)) {
                return list.get(0);
            }
        }
        return null;
    }


}